/****************************************************
	文件：GaussianBlur.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/8/13 14:46:25
	功能：高斯模糊
*****************************************************/

using System;
using UnityEngine;

namespace RenderingPractice
{
    public class GaussianBlur : PostEffectsBase
    {
        [Range(0, 4), Tooltip("高斯模糊迭代次数")]
        public int Iterations = 3;
        [Range(0.2f, 3.0f), Tooltip("模糊范围")]
        public float BlurSpread = 0.6f;
        [Range(1, 8), Tooltip("缩放系数")]
        public int DownSample = 2;

        public Shader GaussianBlurShader;
        private Material mGaussianBlurMat;

        public Material GaussianBlurMat
        {
            get
            {
                mGaussianBlurMat = CheckShaderAndCreateMaterial(GaussianBlurShader, mGaussianBlurMat);
                return mGaussianBlurMat;
            }
        }

        private void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if (GaussianBlurMat != null)
            {
                int rtWidth = source.width / DownSample; //降采样（提升性能、模糊效果）
                int rtHeight = source.height / DownSample;
                RenderTexture buffer0 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0); //获取一个中间缓冲，存储高斯模糊Shader第一个Pass的结果
                buffer0.filterMode = FilterMode.Bilinear; //双线性滤波
                Graphics.Blit(source, buffer0);

                for (int i = 1; i <= Iterations; i++)
                {
                    GaussianBlurMat.SetFloat("_BlurSize", 1.0f + i * BlurSpread);
                    RenderTexture buffer1 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0);
                    //使用竖直方向上的一维高斯核进行滤波（第一个Pass）
                    Graphics.Blit(buffer0, buffer1, GaussianBlurMat, 0);
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                    buffer1 = RenderTexture.GetTemporary(rtWidth, rtHeight, 0);
                    //使用水平方向上的一维高斯核进行滤波（第二个Pass）
                    Graphics.Blit(buffer0, buffer1, GaussianBlurMat, 1);
                    RenderTexture.ReleaseTemporary(buffer0);
                    buffer0 = buffer1;
                }
                Graphics.Blit(buffer0, destination);
                RenderTexture.ReleaseTemporary(buffer0); //释放中间缓冲
            }
            else
            {
                Graphics.Blit(source, destination);
            }
        }
    }
}
